package com.qili.controller.supervisor;
import com.qili.base.entity.CurrentMenu;
import com.qili.base.entity.CurrentRole;
import com.qili.base.entity.CurrentUser;
import com.qili.core.annotation.Log;
import com.qili.core.shiro.Principal;
import com.qili.entity.base.BaseDict;
import com.qili.entity.supervisor.SupervisorFile;
import com.qili.entity.sys.SysRoleUser;
import com.qili.entity.sys.SysUser;
import com.qili.entity.sys.dto.SysRoleUserDTO;
import com.qili.entity.sys.dto.SysUserDTO;
import com.qili.redis.RedisService;
import com.qili.service.SysUserService;
import com.qili.service.supervisor.SupervisorFileService;
import com.qili.service.sys.EmailCodeService;
import com.qili.service.sys.RoleUserService;
import com.qili.service.sys.impl.EmailServiceImpl;
import com.qili.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import tk.mybatis.mapper.entity.Example;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhuxiaomeng
 * @date 2017/12/4.
 * @email 154040976@qq.com
 * 登录、退出页面
 */
@Controller
@Slf4j
public class LoginController {

    @Autowired
    SysUserService userService;
    @Autowired
    private EmailCodeService emailCodeService;
    @Autowired
    private EmailServiceImpl emailService;
    @Autowired
    private SupervisorFileService supervisorFileService;
    @Autowired
    private RedisService redisService;

    @Autowired
    SysUserService sysUserService;

    @Autowired
    private RoleUserService roleUserService;

    private static final String CODE_ERROR = "code.error";



    @GetMapping(value = "")
    public String _index() {
        Subject sub = SecurityUtils.getSubject();
        if (sub.isAuthenticated()) {
            return "/main/main";
        } else {
            return "/index";
        }
    }

    @GetMapping(value = "/index")
    public String index() {
        return "/index";
    }

    @GetMapping(value = "goLogin")
    public String goLogin(Model model) {
        Subject sub = SecurityUtils.getSubject();
        if (sub.isAuthenticated()) {
            return "/main/main";
        } else {
            model.addAttribute("message", "请重新登录");
            return "/login";
        }
    }
    /**
     * @Description:
     * @Author:Zhangshuo
     * @param request
     * @Date:21:02 2020-12-17
     */
    @GetMapping(value = "/register")
    public String _register(HttpServletRequest request) {
        Subject sub = SecurityUtils.getSubject();
        Boolean flag2 = sub.isRemembered();
        boolean flag = sub.isAuthenticated() || flag2;
        if (flag) {
            return "/main/main";
        }
        request.setAttribute("type","register");
        return "/login";
    }

    @GetMapping(value = "/login")
    public String loginCheck(HttpServletRequest request) {
        Subject sub = SecurityUtils.getSubject();
        Boolean flag2 = sub.isRemembered();
        boolean flag = sub.isAuthenticated() || flag2;
        System.out.println("登录================登录============登录============");
        if (flag) {
            if(StringUtil.isBlank(CommonUtil.getUserId())){
                System.out.println("需要重新登录========================================");
                request.setAttribute("type","login");
                return "/login";
            }
            SupervisorFile supervisorFile =  supervisorFileService.getPersonalImg(CommonUtil.getUserId());
            request.setAttribute("file", supervisorFile);
            return "/main/main";
        }
        request.setAttribute("type","login");
        return "/login";
    }
    /**
     * 登录动作
     *
     * @param user
     * @param model
     * @param rememberMe
     * @return
     */
    @ApiOperation(value = "/login", httpMethod = "POST", notes = "登录method")
    @PostMapping(value = "/login")
    public String login(SysUser user, Model model, String rememberMe, HttpSession session,String code) {
        Object codeObj = redisService.get(session.getId()+"code");
        if(null == codeObj){
            throw new RuntimeException("没有获取到验证码");
        }
        String realCode = (String)codeObj;
        if (!realCode.toLowerCase().equals(code.toLowerCase())) {
            model.addAttribute("message", "验证码错误");
            return "/login";
        }
        CustomUsernamePasswordToken token = new CustomUsernamePasswordToken(user.getUsername().trim(), user.getPassword(), "UserLogin",rememberMe);
        Subject subject = Principal.getSubject();
        String msg = null;
        try {
            subject.login(token);
            if (subject.isAuthenticated()) {
                token.getUsername();
                Example example = new Example(SysUser.class);
                example.and().andEqualTo("username",user.getUsername());
                SysUser thisUser = userService.selectOneByExample(example);
                SysUser updateUser = new SysUser();
                updateUser.setLastLoginTime(DateUtil.getCurrentDateTimeString());
                userService.updateByExampleSelective(updateUser,example);

                SysRoleUserDTO sysRoleUserDTO=new SysRoleUserDTO();
                sysRoleUserDTO.setUserId(thisUser.getId());
                List<SysRoleUserDTO> ListsysRoleUserDTOS = sysUserService.selectRoleUserByUser(sysRoleUserDTO);
                redisService.set("ni",ListsysRoleUserDTOS.toString(),30L);

//                AuthorizationInfo info = getAuthorizationInfo(principal);
//                System.out.println(s);
                //


                if(StringUtils.isBlank(thisUser.getLastLoginTime())){
                    //第一次登录，做个标记：
                    return "redirect:/main?firstLogin=1";
                }
                session.setAttribute("username",thisUser.getUsername());
                return "redirect:/main";
            }
        } catch (UnknownAccountException | IncorrectCredentialsException e) {
            msg = "用户名/密码错误";
        } catch (ExcessiveAttemptsException e) {
            msg = "登录失败多次，账户锁定10分钟";
        }
        if (msg != null) {
            model.addAttribute("message", msg);
        }
        return "/login";
    }

    @GetMapping("/main")
    public String main(HttpServletRequest request,String firstLogin,Model model) {
        //获取用户信息:
        String id = CommonUtil.getUserId();
        SysUserDTO user = userService.selectUserById(id);
        if(user==null){
            // 跳转到登陆页面
            request.setAttribute("type","login");
            return "/login";
        }
        request.setAttribute("user", user);
        SupervisorFile supervisorFile=new SupervisorFile();
        supervisorFile.setProjectId(user.getId());
        //supervisorFile.setType("101");
        supervisorFile =  supervisorFileService.getPersonalImg(user.getId());
        request.setAttribute("file", supervisorFile);
        if(StringUtils.isNotBlank(firstLogin) && "1".equals(firstLogin)){
            //如果该用户没有设置邮箱，提示
            if(StringUtils.isBlank(user.getEmail())){
                model.addAttribute("noticeMessage","为方便后期密码找回，请完善个人信息");
            }
        }
        return "main/main";
    }

    /*
     *  首页左侧内容显示
     *
     * */
    @GetMapping("/main_right")
    public String main_right() {
        return "main/main_right";
    }


    @Log(desc = "用户退出平台")
    @GetMapping(value = "/logout")
    public String logout() {
        Subject sub = SecurityUtils.getSubject();
        sub.logout();
        return "/login";
    }


    @GetMapping(value = "/getCode")
    public void getYzm(HttpServletResponse response, HttpSession session) {
        try {
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpg");
            //生成随机字串
            String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
            //存入会话session
            redisService.set(session.getId() + "code", verifyCode.toLowerCase(), 600L);
            //生成图片
            int w = 146, h = 33;
            VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * @Author:zhaoyongke
     * @Description:跳转到后台管理
     * @param null
     * @Date:13:10 2020/11/6
     */
    @RequiresPermissions(value = "menu:show")
    @GetMapping(value = "/toAdmin")
    public String toAdmin() {
        return "/main/admin";
    }

}
